import { getIcon } from "@/utils";

export default G6 => {

  G6.registerNode('rect-node', {
    shapeType: 'rect',
    getShapeStyle(cfg) {
      const width = cfg.style.width || 80;
      const height = cfg.style.height || 40;
      return {
        anchorPointStyles: { r: 4, fill: '#fff', stroke: '#1890FF', lineWidth: 1 },
        r: 5,
        ...cfg,
        ...cfg.style,
        x: -width / 2,
        y: -height / 2,
      }
    },
    update(cfg, item) {
      const group = item.getContainer();
      const [shape, label] = group.findAll(g => g.get('xShapeNode'));

      const width = shape.attr('width');
      const height = shape.attr('height');

      const cfgWidth = cfg.style.width || 80;
      const cfgHeight = cfg.style.height || 40;

      label.attr({ x: (width - cfgWidth) / 2, y: (height - cfgHeight) / 2 });
    }
  }, 'base-node');

  G6.registerNode('circle-node', {
    shapeType: 'circle',
    getShapeStyle(cfg) {
      return {
        anchorPointStyles: { r: 4, fill: '#fff', stroke: '#1890FF', lineWidth: 1 },
        ...cfg,
        ...cfg.style,
        x: 0,
        y: 0,
      };
    }
  }, 'base-node');

  G6.registerNode('ellipse-node', {
    shapeType: 'ellipse',
    getShapeStyle(cfg) {
      return {
        anchorPointStyles: { r: 4, fill: '#fff', stroke: '#1890FF', lineWidth: 1 },
        ...cfg,
        x: 0,
        y: 0,
        ...cfg.style,
      };
    }
  }, 'base-node');

  G6.registerNode('diamond-node', {
    shapeType: 'path',
    getShapeStyle(cfg) {
      return {
        anchorPointStyles: { r: 4, fill: '#fff', stroke: '#1890FF', lineWidth: 1 },
        path: this.getPath(cfg),
        ...cfg,
        ...cfg.style,
        x: 0,
        y: 0,
      };
    },
    getPath(cfg) {
      const { width = 50, height = 50 } = cfg.style;
      //  / 1 \
      // 4     2
      //  \ 3 /
      return [
        ['M', 0, -height], // 上部顶点
        ['L', width, 0], // 右侧顶点
        ['L', 0, height], // 下部顶点
        ['L', -width, 0], // 左侧顶点
        ['Z'], // 封闭
      ];
    },
    update(cfg, item) {
      const group = item.getContainer();
      const [shape] = group.findAll(child => child.get('xShapeNode'));
      shape.attr('fill', shape.get('attrs').fill);
    }
  }, 'base-node');

  G6.registerNode('triangle-node', {
    shapeType: 'path',
    getShapeStyle(cfg) {
      return {
        anchorPointStyles: { r: 4, fill: '#fff', stroke: '#1890FF', lineWidth: 1 },
        direction: cfg.direction || 'up',
        path: this.getPath(cfg),
        ...cfg,
        ...cfg.style,
        x: 0,
        y: 0
      }
    },
    getLabelStyle(cfg, labelCfg, group) {
      const direction = cfg.direction || 'up';
      const isUp = direction === 'up';
      const { height = 50 } = cfg.style;
      return {
        x: 0,
        y: isUp ? -height * 0.25 : height * 0.25,
        textAlign: 'center',
        fill: '#000',
        text: cfg.label,
        ...labelCfg.style,
      }
    },
    getPath(cfg) {
      const direction = cfg.direction || 'up';
      const { width = 50, height = 50 } = cfg.style;
      const path = [['Z']];

      switch (direction) {
        case 'up':
          path.unshift(['M', 0, -height], ['L', -width, 0], ['L', width, 0]); // 上部顶点、左侧顶点、右侧顶点
          break;

        case 'down':
          path.unshift(['M', 0, height], ['L', -width, 0], ['L', width, 0]);  // 下部顶点、左侧顶点、右侧顶点
          break;

        case 'left':
          path.unshift(['M', -width, 0], ['L', 0, -height], ['L', 0, height]); // 左侧顶点、上部顶点、下部顶点
          break;

        case 'right':
          path.unshift(['M', width, 0], ['L', 0, -height], ['L', 0, height]); // 右侧顶点、上部顶点、下部顶点
          break;

        default:
          break;
      }

      return path;
    },
    update(cfg, item) {
      const group = item.getContainer();
      const [shape, label] = group.findAll(child => child.get('xShapeNode'));
      const direction = shape.get('attrs').direction || 'up';

      const width = shape.get('attrs').width;
      const height = shape.get('attrs').height;

      switch (direction) {
        case 'up':
          label.attr({ x: 0, y: -height * 0.25 });
          shape.attr('path', [['M', 0, -height], ['L', -width, 0], ['L', width, 0], ['Z']]);
          break;

        case 'down':
          label.attr({ x: 0, y: height * 0.25 });
          shape.attr('path', [['M', 0, height], ['L', -width, 0], ['L', width, 0], ['Z']]);
          break;

        case 'left':
          label.attr({ x: -width * 0.25, y: 0 });
          shape.attr('path', [['M', -width, 0], ['L', 0, -height], ['L', 0, height], ['Z']]);
          break;

        case 'right':
          label.attr({ x: width * 0.25, y: 0 });
          shape.attr('path', [['M', width, 0], ['L', 0, -height], ['L', 0, height], ['Z']]);
          break;

        default:
          label.attr({ x: 0, y: -height * 0.25 });
          shape.attr('path', [['M', 0, -height], ['L', -width, 0], ['L', width, 0], ['Z']]);
          break;
      }


    },
    getAnchorPoints(cfg, group) {

      let direction = cfg.direction || 'up';

      if (group) {
        const [shape] = group.findAll(child => child.get('xShapeNode'));
        direction = shape.get('attrs').direction || 'up';
      }

      switch (direction) {
        case 'up':
          return [
            [0.5, 0],
            [0, 1],
            [1, 1],
          ];

        case 'down':
          return [
            [0.5, 1],
            [0, 0],
            [1, 0],
          ];

        case 'left':
          return [
            [0, 0],
            [0, 0.5],
            [0, 1],
          ];

        case 'right':
          return [
            [1, 0],
            [1, 0.5],
            [1, 1],
          ];

        default:
          return [
            // [0, 0.5],
            // [0.5, 0],
            // [1, 0],
          ];
      }

    },
  }, 'base-node');

  G6.registerNode('icon-node', {

    draw(cfg, group) {

      const keyShape = group.addShape('circle', {
        name: 'circle-shape',
        xShapeNode: true,
        draggable: true,
        attrs: {
          anchorPointStyles: { r: 4, fill: '#fff', stroke: '#1890FF', lineWidth: 1 },
          type: 'icon-node',
          ...cfg,
          ...this.getShapeStyle(cfg),
          x: 0,
          y: 0,
        },
      });

      const { iconCfg, iconCfg: { width, height } } = cfg;
      const shape = group.addShape('text', {
        name: 'icon-shape',
        xShapeNode: true,
        draggable: true,
        attrs: {
          fontFamily: 'iconfont',
          textAlign: 'center',
          textBaseline: 'middle',
          fontSize: 40,
          fill: '#000',
          icon: cfg.icon,
          text: getIcon(cfg.icon),
          ...iconCfg,
          fontSize: Math.sqrt(width * width + height * height) / 2,
          x: 0,
          y: 0,
        },
      });
      function fn(ratio) {
        const ratio1 = ratio < 0.5 ? ratio * 2 : (1 - ratio) * 2;
        return {
          fontSize: shape.get('attrs').fontSize * (1 + ratio1 * 0.2),
          fill: shape.get('attrs').fill,
          opacity: ratio1 < 0.6 ? 0.6 : ratio1,
        };
      }
      // function fn2(ratio) {
      //   const matrix = [
      //     1, 0, 0,
      //     0, 1, 0,
      //     0, 0, 1
      //   ];
      //   const toMatrix = G6.Util.transform(matrix, [['r', ratio * Math.PI * 2]]);
      //   return { matrix: toMatrix, };
      // };
      shape.animate(fn, { repeat: true, duration: 3000, easing: 'easePolyIn' });

      const { labelCfg } = cfg;

      group.addShape('text', {
        name: 'label-shape',
        xShapeNode: true,
        draggable: true,
        xShapeNode: true,
        attrs: {
          x: 0,
          y: 60,
          textAlign: 'center',
          fill: '#000',
          text: cfg.label,
          ...labelCfg.style,
        },
      });

      return keyShape;
    },
    update(cfg, item) { },

  }, 'anchor-node');

};
